package com.xmy.cultivate.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xmy.cultivate.entity.*;
import com.xmy.cultivate.service.*;
import com.xmy.cultivate.util.Code;
import com.xmy.cultivate.util.PageResult;
import com.xmy.cultivate.util.Result;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.stereotype.Controller;

import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 支出表 前端控制器
 * </p>
 *
 * @author hpiggy
 * @since 2025-05-17
 */
@RestController
@RequestMapping("/api/admin/fincDisburse")
public class FincDisburseController extends BaseController{

    @Autowired
    IStaffService iStaffService;
    @Autowired
    IFincDisburseService iFincDisburseService;
    @Autowired
    IFincTypeService iFincTypeService;
    @Autowired
    IOrganizationService iOrganizationService;
    @Autowired
    IDepartmentService iDepartmentService;

    /**
     * 获取校区
     */
    @GetMapping("/getSchoolAndDepart")
    public Result getSchoolAndDepart() {

        List<Map<String, Object>> schoolAndDepart = iFincDisburseService.getSchoolAndDepart();

        return new Result(Code.OK, schoolAndDepart,  "获取校区成功");

    }

    @GetMapping("/findAll")
    public Result findAll(@RequestParam(value = "pageNum", defaultValue = "1", required = false) Integer pageNum,
                          @RequestParam(value = "pageSize", defaultValue = "10", required = false) Integer pageSize,
                          @RequestParam(value = "export", defaultValue = "0", required = false) Integer export,
                          @RequestParam(value = "yearPart", required = false) String yearPart,  //年份
                          @RequestParam(value = "quarterNum", required = false) String quarterNum, //学期
                          @RequestParam(value = "handleName", required = false) String handleName, //姓名
                          @RequestParam(value = "fincTypeId", required = false) String fincTypeId,     //支出类型ID
                          @RequestParam(value = "fincTypeSubId", required = false) String fincTypeSubId,     //子支出类型ID
                          @RequestParam(value = "schoolOrDepartmentId", required = false) String schoolOrDepartmentId,
                          @RequestParam(value = "startDate", required = false) String startDate,
                          @RequestParam(value = "endDate", required = false) String endDate
//                          @RequestParam(value = "handleDate", required = false) String handleDate
                         ) throws IOException {
        IPage<FincDisburse> iPage = new Page<>(pageNum, pageSize);
        iFincDisburseService.findAll(iPage, yearPart, quarterNum, handleName, fincTypeId, fincTypeSubId, schoolOrDepartmentId, startDate, endDate);
        for (FincDisburse fincDisburse : iPage.getRecords()){
            if (fincDisburse.getDepartmentId() !=  null){
                Department department = iDepartmentService.getById(fincDisburse.getDepartmentId());
                if (department != null) {
                    fincDisburse.setSchoolName(department.getName());
                    fincDisburse.setSchoolOrDepartmentId(fincDisburse.getDepartmentId());
                }
            }else {
                fincDisburse.setSchoolOrDepartmentId(fincDisburse.getSchoolId());
            }

            FincType fincType = iFincTypeService.getById(fincDisburse.getFincTypeSubId());
            if (fincType != null){
                fincDisburse.setFincTypeSubName(fincType.getName());
            }

        }
        if (export == 1) {
            Workbook workbook = new XSSFWorkbook();
            Sheet sheet = workbook.createSheet("支出数据");
            CellStyle headerCellStyle = workbook.createCellStyle();
            Font headerFont = workbook.createFont();
            headerFont.setFontHeightInPoints((short) 11);
            headerCellStyle.setFont(headerFont);
            headerCellStyle.setAlignment(HorizontalAlignment.CENTER);
            headerCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
            Row headerRow = sheet.createRow(0);
            sheet.createFreezePane(0, 1);// 冻结首行

            CellStyle cellStyle = workbook.createCellStyle();
            cellStyle.setFont(headerFont);
            cellStyle.setAlignment(HorizontalAlignment.CENTER);
            cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);

            List<String> headList = new ArrayList<>();
            headList.add("校区");
            headList.add("日期");
            headList.add("经手人");
            headList.add("支出类型");
            headList.add("子支出类型");
            headList.add("支出明细");
            headList.add("支出金额(元)");
            headList.add("备注");

            for (int i = 0; i < headList.size(); i++) {
                Cell cell = headerRow.createCell(i);
                cell.setCellValue(headList.get(i));
                cell.setCellStyle(headerCellStyle);
            }
            int rowIndex = 1;// 数据行起始索引
            for (FincDisburse fincDisburse : iPage.getRecords()) {
                Row row = sheet.createRow(rowIndex++);

                Cell cell1 = row.createCell(0);
                cell1.setCellValue(fincDisburse.getSchoolName());
                sheet.setColumnWidth(0, 15 * 256);
                cell1.setCellStyle(cellStyle);

                Cell cell2 = row.createCell(1);
                cell2.setCellValue(String.valueOf(fincDisburse.getHandleDate()));
                sheet.setColumnWidth(1, 15 * 256);
                cell2.setCellStyle(cellStyle);

                Cell cell3 = row.createCell(2);
                cell3.setCellValue(fincDisburse.getHandleName());
                sheet.setColumnWidth(2, 15 * 256);
                cell3.setCellStyle(cellStyle);

                Cell cell4 = row.createCell(3);
                cell4.setCellValue(fincDisburse.getFincTypeName());
                sheet.setColumnWidth(3, 15 * 256);
                cell4.setCellStyle(cellStyle);


                Cell cell5 = row.createCell(4);
                cell5.setCellValue(fincDisburse.getFincTypeSubName());
                sheet.setColumnWidth(4, 15 * 256);
                cell5.setCellStyle(cellStyle);

                Cell cell6 = row.createCell(5);
                cell6.setCellValue(fincDisburse.getDisburseDetail());
                sheet.setColumnWidth(5, 15 * 256);
                cell6.setCellStyle(cellStyle);

                Cell cell7 = row.createCell(6);
                cell7.setCellValue(fincDisburse.getDisbursePrice().toString());
                sheet.setColumnWidth(6, 15 * 256);
                cell7.setCellStyle(cellStyle);

                Cell cell8 = row.createCell(7);
                cell8.setCellValue(fincDisburse.getRemark());
                sheet.setColumnWidth(7, 15 * 256);
                cell8.setCellStyle(cellStyle);

            }

            String fileName = "支出数据导出" + ".xlsx";
            String encodedFileName = URLEncoder.encode(fileName, "UTF-8");

            response.setContentType("application/zip");
            response.setHeader("Content-Disposition", "attachment; filename=" + encodedFileName);
            // 获取响应输出流
            OutputStream outputStream = response.getOutputStream();
            // 将工作簿写入输出流
            workbook.write(outputStream);
            // 关闭工作簿
            workbook.close();
            // 刷新输出流
            outputStream.flush();
            //关闭输出流
            outputStream.close();

        }


        return new Result(Code.OK, new PageResult(iPage.getRecords(), iPage.getTotal(), iPage.getPages()));
    }


    @DeleteMapping("/delete")
    public Result delete(@RequestBody FincDisburse fincDisburse) {
        FincDisburse fincDisburse1 = iFincDisburseService.getById(fincDisburse.getId());
        if (fincDisburse1 == null){
            return new Result(Code.DELETE_ERROR, null, "该数据不存在,无法删除");
        }
        boolean remove = iFincDisburseService.removeById(fincDisburse.getId());
        if (remove){
            return new Result(Code.DELETE_OK, null, Code.DELETE_OK_MSG);
        }
        return new Result(Code.DELETE_ERROR, null, Code.DELETE_ERROR_MSG);
    }




    @GetMapping("/handleName")
    public Result handleName() {
        Staff staff = iStaffService.getById(this.adminId);
        HashMap<String, Object> map = new HashMap<>();
        if (staff != null){
            map.put("handleName", staff.getName());
            map.put("handleId", staff.getId());
        }
        return new Result(Code.GET_OK, map, Code.GET_OK_MSG);
    }

    @PostMapping("/addFincDisburse")
    public Result addFincDisburse(@RequestBody FincDisburse fincDisburse) {
        if (fincDisburse.getId() == null) {
            if (fincDisburse.getSchoolOrDepartmentId() == null){
                return new Result(Code.SAVE_ERROR, null, "请选择校区");
            }
            Long schoolOrDepartmentId = fincDisburse.getSchoolOrDepartmentId();
            Organization organization = iOrganizationService.getById(schoolOrDepartmentId);
            if (organization == null){
                fincDisburse.setDepartmentId(fincDisburse.getSchoolOrDepartmentId());
                fincDisburse.setSchoolId(1600466723094175746L);
            }else {
                fincDisburse.setSchoolId(fincDisburse.getSchoolOrDepartmentId());
            }


            fincDisburse.setCreatedId(this.adminId);
            boolean save = iFincDisburseService.save(fincDisburse);
            if (save) {
                return new Result(Code.SAVE_OK, null, Code.SAVE_OK_MSG);
            }
            return new Result(Code.SAVE_ERROR, null, Code.SAVE_ERROR_MSG);
        } else {
            FincDisburse fincDisburse1 = iFincDisburseService.getById(fincDisburse.getId());
            if (fincDisburse1 == null){
                return new Result(Code.SAVE_ERROR, null, "该数据不存在,无法修改");
            }

            if (fincDisburse.getSchoolOrDepartmentId() == null){
                return new Result(Code.SAVE_ERROR, null, "请选择校区");
            }
            Long schoolOrDepartmentId = fincDisburse.getSchoolOrDepartmentId();
            Organization organization = iOrganizationService.getById(schoolOrDepartmentId);
            if (organization == null){
                fincDisburse.setDepartmentId(fincDisburse.getSchoolOrDepartmentId());
                fincDisburse.setSchoolId(1600466723094175746L);
            }else {
                fincDisburse.setSchoolId(fincDisburse.getSchoolOrDepartmentId());
            }

            fincDisburse.setCreatedId(this.adminId);
            boolean update = iFincDisburseService.updateFincDisburseInfo(fincDisburse.getSchoolId(), fincDisburse.getDepartmentId(), fincDisburse.getFincTypeId(), fincDisburse.getFincTypeSubId(),
                    fincDisburse.getHandleId(), fincDisburse.getHandleDate().toString(), fincDisburse.getDisbursePrice(), fincDisburse.getDisburseDetail(), fincDisburse.getRemark(), this.adminId, fincDisburse.getId());
//            boolean update = iFincDisburseService.updateById(fincDisburse);
            if (update) {
                return new Result(Code.UPDATE_OK, null, Code.UPDATE_OK_MSG);
            }
            return new Result(Code.UPDATE_ERROR, null, Code.UPDATE_ERROR_MSG);
        }
    }



/*
    @GetMapping("/fincDisburseCount")
    public Result fincDisburseCount(@RequestParam(value = "pageNum", defaultValue = "-1", required = false) Integer pageNum,
                          @RequestParam(value = "pageSize", defaultValue = "-1", required = false) Integer pageSize,
                          @RequestParam(value = "export", defaultValue = "0", required = false) Integer export,
                          @RequestParam(value = "yearPart", required = false) String yearPart,  //年份
                          @RequestParam(value = "quarterNum", required = false) String quarterNum, //学期
                          @RequestParam(value = "fincTypeId", required = false) String fincTypeId,     //支出类型ID
                          @RequestParam(value = "fincTypeSubId", required = false) String fincTypeSubId,     //子支出类型ID
                          @RequestParam(value = "startDate", required = false) String startDate,
                          @RequestParam(value = "endDate", required = false) String endDate

    ) throws IOException {
        IPage<FincDisburse> iPage = new Page<>(pageNum, pageSize);
        iFincDisburseService.fincDisburseCount(iPage, yearPart, quarterNum, fincTypeId, fincTypeSubId, startDate, endDate);
        for (FincDisburse fincDisburse : iPage.getRecords()) {

            FincType fincType = iFincTypeService.getById(fincDisburse.getFincTypeSubId());
            if (fincType != null) {
                fincDisburse.setFincTypeSubName(fincType.getName());
            }

        }
        return new Result(Code.OK, new PageResult(iPage.getRecords(), iPage.getTotal(), iPage.getPages()));
    }
*/


    @GetMapping("/fincDisburseCount")
    public Result fincDisburseCount(@RequestParam(value = "pageNum", defaultValue = "-1", required = false) Integer pageNum,
                                    @RequestParam(value = "pageSize", defaultValue = "-1", required = false) Integer pageSize,
                                    @RequestParam(value = "export", defaultValue = "0", required = false) Integer export,
                                    @RequestParam(value = "yearPart", required = false) String yearPart,  //年份
                                    @RequestParam(value = "quarterNum", required = false) String quarterNum, //学期
                                    @RequestParam(value = "fincTypeId", required = false) String fincTypeId,     //支出类型ID
                                    @RequestParam(value = "fincTypeSubId", required = false) String fincTypeSubId,     //子支出类型ID
                                    @RequestParam(value = "startDate", required = false) String startDate,
                                    @RequestParam(value = "endDate", required = false) String endDate

    ) throws IOException {
        List<FincDisburse> getFincDisburse = iFincDisburseService.getFincDisburse(yearPart, quarterNum, fincTypeId, fincTypeSubId, startDate, endDate);
        List<FincDisburse> fincDisburseFindAll = iFincDisburseService.getFincDisburseFindAll(yearPart, quarterNum, fincTypeId, fincTypeSubId, startDate, endDate);
        for ( FincDisburse fincDisburse : fincDisburseFindAll){
            if (fincDisburse.getDepartmentId() !=  null){
                Department department = iDepartmentService.getById(fincDisburse.getDepartmentId());
                if (department != null) {
                    fincDisburse.setSchoolOrDepartmentName(department.getName());

                }
            }

        }        // 构建 Map：以 (fincTypeId:fincTypeSubId) 为 key，value 是对应的 FincDisburse 列表
        Map<String, List<FincDisburse>> groupedMap = new HashMap<>();
        for (FincDisburse item : fincDisburseFindAll) {
            String key = item.getFincTypeId() + ":" + item.getFincTypeSubId();
            groupedMap.computeIfAbsent(key, k -> new ArrayList<>()).add(item);
        }

        // 遍历 getFincDisburse 并赋值
        for (FincDisburse item : getFincDisburse) {
            String key = item.getFincTypeId() + ":" + item.getFincTypeSubId();
            if (groupedMap.containsKey(key)) {
                item.setFincDisburseList(groupedMap.get(key)); // 设置 fincDisburseList
            }
        }

        if (export == 1) {
            Workbook workbook = new XSSFWorkbook();
            Sheet sheet = workbook.createSheet("支出汇总数据");
            CellStyle headerCellStyle = workbook.createCellStyle();
            Font headerFont = workbook.createFont();
            headerFont.setFontHeightInPoints((short) 11);
            headerCellStyle.setFont(headerFont);
            headerCellStyle.setAlignment(HorizontalAlignment.CENTER);
            headerCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
            Row headerRow = sheet.createRow(0);
            sheet.createFreezePane(0, 1);// 冻结首行

            CellStyle cellStyle = workbook.createCellStyle();
            cellStyle.setFont(headerFont);
            cellStyle.setAlignment(HorizontalAlignment.CENTER);
            cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);

            List<String> headList = new ArrayList<>();
            List<Map<String, Object>> schoolAndDepart = iFincDisburseService.getSchoolAndDepart();
            List<String> schoolOrDepartmentName = schoolAndDepart.stream()
                    .map(map -> (String) map.get("school_or_department_name")) // 假设 "name" 是校区/部门的名称字段
                    .collect(Collectors.toList());
            headList.add("支出类型");
            headList.add("子支出类型");
            headList.addAll(schoolOrDepartmentName); // 添加动态列
            headList.add("合计");


            for (int i = 0; i < headList.size(); i++) {
                Cell cell = headerRow.createCell(i);
                cell.setCellValue(headList.get(i));
                cell.setCellStyle(headerCellStyle);
            }
            int rowIndex = 1;// 数据行起始索引
            for (FincDisburse mainItem : getFincDisburse) {
                Row row = sheet.createRow(rowIndex++);

                Cell cell1 = row.createCell(0);
                cell1.setCellValue(mainItem.getFincTypeName());
                sheet.setColumnWidth(0, 15 * 256);
                cell1.setCellStyle(cellStyle);

                Cell cell2 = row.createCell(1);
                cell2.setCellValue(mainItem.getFincTypeSubName());
                sheet.setColumnWidth(1, 15 * 256);
                cell2.setCellStyle(cellStyle);
                int totalAmount = 0; // 合计金额

                // 动态列数据填充
                for (int colIndex = 2; colIndex < headList.size(); colIndex++) {
                    String schoolOrDepartName = headList.get(colIndex);
                    Integer value = 0; // 默认值

                    if (mainItem.getFincDisburseList() != null) {
                        for (FincDisburse subItem : mainItem.getFincDisburseList()) {
                            if ( schoolOrDepartName.equals(subItem.getSchoolOrDepartmentName())) {
                                value = subItem.getTotalDisbursePrice() != null ? subItem.getTotalDisbursePrice().intValue() : 0;
                                break;
                            }
                        }
                    }

                    row.createCell(colIndex).setCellValue(value);
                    totalAmount += value;
                }
                // 合计列（最后一列）
                row.createCell(headList.size() - 1).setCellValue(totalAmount);

            }

            String fileName = "支出统计汇总" + ".xlsx";
            String encodedFileName = URLEncoder.encode(fileName, "UTF-8");

            response.setContentType("application/zip");
            response.setHeader("Content-Disposition", "attachment; filename=" + encodedFileName);
            // 获取响应输出流
            OutputStream outputStream = response.getOutputStream();
            // 将工作簿写入输出流
            workbook.write(outputStream);
            // 关闭工作簿
            workbook.close();
            // 刷新输出流
            outputStream.flush();
            //关闭输出流
            outputStream.close();

        }
        return new Result(Code.OK, getFincDisburse, Code.OK_MSG);

    }

}
